package org.liquidByte.trafficMustang.androidApp.listview.adapter;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.liquidByte.trafficMustang.androidApp.listview.row.ListViewRow;
import org.liquidByte.trafficMustang.androidApp.listview.row.ModelListViewRow;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

public abstract class RowAdapter<T> extends BaseAdapter {
	private List<T> list;
	private LayoutInflater inflater;
	private Context parent;
	private View.OnClickListener clickListener;

	protected RowAdapter(Context ctx) {
		super();
		this.inflater = LayoutInflater.from(ctx);
		this.parent = ctx;
	}
	
	protected abstract int getViewResource();
	
	protected LayoutInflater getInflater() {
		return this.inflater;
	}

	protected Context getParent() {
		return parent;
	}

	protected List<T> getList() {
		if (this.list == null) {
			this.list = new ArrayList<T>();
		}
		return list;
	}
	
	public void setOnClickListener(View.OnClickListener listener) {
		if (listener != null) {
			if (this.getCount() > 0) {
				throw new java.lang.IllegalAccessError("rowAdapter must be empty to register click listener"); 
			}
			this.clickListener = listener;
		}
	}

	@Override
	public int getCount() {
		return this.getList().size();
	}

	@Override
	public Object getItem(int position) {
		if (position < this.getList().size()) {
			return this.getList().get(position);
		} else {
			return null;
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		T item = (T)this.getItem(position);
		if (item == null) {
			return null;
		} else {
			View view = convertView;
			if (view != null && view.getId() != this.getViewResource()) {
				view = null;
			}
			ListViewRow row = null;
			if (view == null) {
				view = this.createRowView();
				row = this.createBoundedRow(view);
			} else {
				row = this.createBoundedRow(view);
			}
			if (row instanceof ModelListViewRow<?>) {
				ModelListViewRow<T> modelRow = (ModelListViewRow<T>)row;
				
				if (modelRow.getModel() == null || !modelRow.getModel().equals(item)) {
					modelRow.setModel(item);
				}
			}
			return view;
		}
	}

	private ListViewRow createBoundedRow(View view) {
		ListViewRow row = this.createRow(view);
		view.setTag(row);
		row.init();
		return row;
	}
	protected View createRowView() {
		View view = this.getInflater().inflate(this.getViewResource(), null);
		view.setId(this.getViewResource());
		if (this.clickListener != null) {
			view.setOnClickListener(this.clickListener);
		}
		return view;
	}	
	protected abstract ListViewRow createRow(View view);
	public void remove(T model) {
		this.getList().remove(model);
		this.notifyDataSetChanged();
	}
	public void clear() {
		this.getList().clear();
		this.notifyDataSetChanged();
	}
	public void put(T model) {
		if (model != null) {
			for (Iterator<T> iter = this.getList().iterator(); iter.hasNext();) {
				T item = iter.next();
				if (model.equals(item)) {
					iter.remove();
					break;
				}
			}
			this.getList().add(model);
			this.notifyDataSetChanged();
		}
	}
}